package _stack_queue

import org.junit.Assert
import org.junit.Test
import java.util.*

/**
 * LinkedList 可以作为栈或队列使用。
 * https://www.runoob.com/java/java-linkedlist.html
 */
class TestLinkedList {
    @Test
    fun test_1() {
        // add item
        // 1 2 3 =>
        val linkedList: LinkedList<Int> = LinkedList<Int>()
        linkedList.addLast(1)
        Assert.assertEquals("[1]", linkedList.toString())

        linkedList.addLast(2)
        Assert.assertEquals("[1, 2]", linkedList.toString())

        linkedList.add(3) // == addLast
        Assert.assertEquals("[1, 2, 3]", linkedList.toString())

        linkedList.addFirst(4)
        Assert.assertEquals("[4, 1, 2, 3]", linkedList.toString())

        linkedList.offer(5) // add to last, return bool
        Assert.assertEquals("[4, 1, 2, 3, 5]", linkedList.toString())

        linkedList.offerLast(6) // add to last, return bool
        Assert.assertEquals("[4, 1, 2, 3, 5, 6]", linkedList.toString())

        linkedList.offerFirst(7) // add to last, return bool
        Assert.assertEquals("[7, 4, 1, 2, 3, 5, 6]", linkedList.toString())

        // get
        // get the first value
        Assert.assertEquals(7, linkedList.element())
        Assert.assertEquals("[7, 4, 1, 2, 3, 5, 6]", linkedList.toString())

        Assert.assertEquals(7, linkedList.peekFirst())
        Assert.assertEquals("[7, 4, 1, 2, 3, 5, 6]", linkedList.toString())

        Assert.assertEquals(6, linkedList.peekLast())
        Assert.assertEquals("[7, 4, 1, 2, 3, 5, 6]", linkedList.toString())

        // index of
        Assert.assertEquals(1, linkedList.indexOf(4))
        Assert.assertEquals(1, linkedList.lastIndexOf(4))

        // delete item
        val actual = linkedList.remove() // remove the first , and return the removed value
        Assert.assertEquals(7, actual)
        Assert.assertEquals("[4, 1, 2, 3, 5, 6]", linkedList.toString())

        val actual2 = linkedList.removeFirst()  // remove the first, and return the removed value
        Assert.assertEquals(4, actual2)
        Assert.assertEquals("[1, 2, 3, 5, 6]", linkedList.toString())

        val actual3 = linkedList.removeLast()  // remove the last, and return the removed value
        Assert.assertEquals(6, actual3)
        Assert.assertEquals("[1, 2, 3, 5]", linkedList.toString())

        val actual4 = linkedList.remove(100)  // remove the target, and return the bool for success or not
        Assert.assertEquals(false, actual4)
        Assert.assertEquals("[1, 2, 3, 5]", linkedList.toString())

        val actual5 = linkedList.poll()  // remove the first, and return the removed value
        Assert.assertEquals(actual5, 1)
        Assert.assertEquals("[2, 3, 5]", linkedList.toString())

        val actual6 = linkedList.pollFirst()  // remove the first, and return the removed value
        Assert.assertEquals(actual6, 2)
        Assert.assertEquals("[3, 5]", linkedList.toString())

        val actual7 = linkedList.pollLast()  // remove the first, and return the removed value
        Assert.assertEquals(actual7, 5)
        Assert.assertEquals("[3]", linkedList.toString())

        Assert.assertEquals(1, linkedList.size)
    }

    @Test
    fun test_stack() {
        val stack: LinkedList<Int> = LinkedList<Int>()

        // 1]
        stack.push(1)
        Assert.assertEquals("[1]", stack.toString())

        // 2 1]
        stack.push(2)
        Assert.assertEquals("[2, 1]", stack.toString())

        Assert.assertEquals(2, stack.peek())
        // 1 ]
        Assert.assertEquals(2, stack.pop())
        Assert.assertEquals("[1]", stack.toString())
    }

    @Test
    fun test_queue() {
        val queue: Queue<Int> = LinkedList<Int>()

        //  < - 1
        queue.offer(1)
        Assert.assertEquals("[1]", queue.toString())

        // < - 1 2
        queue.offer(2)
        Assert.assertEquals("[1, 2]", queue.toString())

        Assert.assertEquals(1, queue.peek())

        // 2 ]
        Assert.assertEquals(1, queue.poll())
        Assert.assertEquals("[2]", queue.toString())
    }
}